﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Medianamik.Core.Sugar;
using Roles = Medianamik.Core.Security.Roles;
using Medianamik.Core;
using Medianamik.Core.Security;
using Medianamik.UI.Controls;
using Medianamik.Core.Logging;
using Group = Medianamik.Core.Security.Group;

namespace Medianamik.UI.SecurityManagement
{
    public partial class GroupList : BasePage
    {
        protected const string BaseUrl = "/medianamik/SecurityManagement/GroupList.aspx?basetypeid=";
        private const string ParentGroupIdParamName = "basetypeid";

        protected void Page_Init(object sender, EventArgs e)
        {
            var previewSecurityWindow = new BaseModalWindow {ID = "PreviewSecurityWindow"};
            var visiblePropertiesWindow = new BaseModalWindow { ID = "VisiblePropertiesWindow" };

            if (!Page.IsPostBack)
            {
                previewSecurityWindow.IconUrl = "/Medianamik/images/Icones/Ico_Visualisation.gif";
                previewSecurityWindow.ReloadOnShow = true;
                previewSecurityWindow.Width = Unit.Pixel(640);
                previewSecurityWindow.Height = Unit.Pixel(480);

                visiblePropertiesWindow.IconUrl = "/Medianamik/images/Icones/Ico_Visualisation.gif";
                visiblePropertiesWindow.ReloadOnShow = true;
                visiblePropertiesWindow.Width = Unit.Pixel(640);
                visiblePropertiesWindow.Height = Unit.Pixel(480);
            }

            MyWindowManager.Windows.Add(previewSecurityWindow);
            MyWindowManager.Windows.Add(visiblePropertiesWindow);
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                groupsTreeView.CurrentItemValue = ParentGroup == null ? "root" :
                    ParentGroup.ID.ToString();

                LoadBreadcrumbs();

                if (MedianamikUser.IsSuperAdmin && ParentGroup == null)
                    AddGroup.NavigateUrl = "javascript:void(alert('Il n\\'est pas possible d\\'ajouter un groupe à ce niveau.'));";
                else
                    AddGroup.NavigateUrl = ManagementUrl;

            }
        }

        protected void GridGroups_NeedDataSource(object sender, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
        {
            if (ParentGroup == null)
                GridGroups.DataSource = GetChildGroups();
            else
                GridGroups.DataSource = GetChildGroups(ParentGroup.ID);
        }

        protected void GridGroups_ItemDataBound(object sender, Telerik.Web.UI.GridItemEventArgs e)
        {
            if (e.Item.ItemType == Telerik.Web.UI.GridItemType.Item
                || e.Item.ItemType == Telerik.Web.UI.GridItemType.AlternatingItem)
            {
                var group = e.Item.DataItem as Group;

                if (group != null)
                {
                    var cmdDelete = e.Item.FindControl("cmdDelete") as ConfirmedImageButton;

                    if (cmdDelete != null)
                    {
                        var enabled = false;

                        if (group.ID.Equals(MedianamikGroups.SuperAdmins))
                        {
                            enabled = Roles.GetUsersInGroup(group.Name).Length == 0;

                        }
                        else
                        {
                            enabled = Roles.GetUsersInGroup(group.Name).Length == 0;
                            //&& Roles.GetRolesInGroup((string)DataBinder.GetPropertyValue(e.Item.DataItem, "Name")).Length == 0;
                        }

                        cmdDelete.Enabled = enabled;

                        if (!enabled)
                        {
                            cmdDelete.Enabled = false;
                            cmdDelete.OnClientClick = "return false;";
                        }

                        cmdDelete.ImageUrl = enabled
                                                 ? "/medianamik/images/Icones/Ico_Supprimer.gif"
                                                 : "/medianamik/images/Icones/Ico_SupprimerInactif.gif";
                    }

                    var previewSecurityLink = e.Item.FindControl("PreviewSecurityLink") as HyperLink;

                    if (previewSecurityLink != null)
                    {
                        if (group.ID.Equals(MedianamikGroups.SuperAdmins))
                        {
                            previewSecurityLink.NavigateUrl = "javascript:void(alert('La sécurité n\\'est pas prise en compte sur le groupe SuperAdmins.'));";
                            previewSecurityLink.Attributes["onclick"] = "";
                            previewSecurityLink.Target = "";
                        }
                        else
                        {
                            previewSecurityLink.NavigateUrl
                                = "/medianamik/modalwindows/securitypreviewwindow.aspx?group=" + group.Name;
                        }
                    }

                    var visiblePropertiesLink = e.Item.FindControl("VisiblePropertiesLink") as HyperLink;

                    if (visiblePropertiesLink != null)
                    {
                        visiblePropertiesLink.NavigateUrl
                                = "/medianamik/modalwindows/VisiblePropertiesWindow.aspx?group=" + group.Name;
                    }
                }
            }
        }

        protected void GridGroups_ItemCommand(object sender, CommandEventArgs e)
        {
            switch (e.CommandName.ToLowerInvariant())
            {
                case "deletegroup":
                    string groupName = e.CommandArgument.ToString();
                    var logger = new ActivityLogger();
                    logger.Log(new LoggableObject(groupName, LogEntryType.Group), "Group Deleted");
                    Roles.DeleteGroup(groupName);
                    GridGroups.Rebind();
                    groupsTreeView.Nodes.Clear();
                    break;
            }
        }

        protected void groupsTreeView_NeedChildren(object sender, NeedChildrenEventArgs e)
        {
            Guid g;
            var parentId = StringHelper.IsGuid(e.ParentValue, out g)
                ? g : default(Guid?);

            IEnumerable<Group> groups;

            if (parentId.HasValue)
            {
                groups = SecurityManager.AllGroups
                    .Where(x => x.ParentID == parentId);

            }
            else
            {
                groups = GetChildGroups();
            }

            e.ChildNodes.AddRange(groups.Select<Group,
                ITreeItem>(x => new TreeItem(x.Name, x.ID.ToString(),
                    BaseUrl + x.ID.ToString(), null, x.ChildrenCount > 0)));
        }

        protected void groupsTreeView_NeedSelfAndParents(object sender, NeedSelfAndParentsEventArgs e)
        {
            Guid g;

            if (StringHelper.IsGuid(e.ItemValue, out g))
            {
                var group = SecurityManager.GetGroup(g);

                var groups = group.GetParentIDs(true)
                    .Select(x => SecurityManager.GetGroup(x))
                    .Select<Group, ITreeItem>(x => new TreeItem(x.Name, x.ID.ToString(), BaseUrl + x.ID.ToString(), null, x.ChildrenCount > 0, true, x.Depth, true));

                e.Items.AddRange(groups);
            }

            e.Items.Add(new TreeItem(SiteMap.CurrentNode.Title, "root", "GroupList.aspx", null, true, true, int.MinValue, true));
        }

        protected string ManagementUrl
        {
            get
            {
                var returnURL = "GroupManagement.aspx";

                if (ParentGroup != null)
                    returnURL += "?basetypeid=" + ParentGroup.ID;

                return returnURL;
            }
        }

        private Group _parentGroup;
        protected Group ParentGroup
        {
            get
            {
                var parentGroupId = GetParentGroupId();

                if (parentGroupId.HasValue && _parentGroup == null)
                {
                    _parentGroup = SecurityManager.GetGroup(parentGroupId.Value);
                }

                return _parentGroup;
            }
        }

        protected Guid? GetParentGroupId()
        {
            return GetQueryStringValue<Guid?>(ParentGroupIdParamName);
        }

        private void LoadBreadcrumbs()
        {
            if (ParentGroup == null)
            {
                bctFilAriane.Visible = false;
            }
            else
            {
                bctFilAriane.Visible = true;
                var crumbs = SecurityManager.GetParentGroups(ParentGroup.ID)
                    .ToList();
                crumbs.Sort((t1, t2) => t1.Depth.CompareTo(t2.Depth));

                var breadcrumbs = crumbs.Select(x => new Breadcrumb(x.ID.ToString(),
                     x.Name)).ToList();

                breadcrumbs.Insert(0, new Breadcrumb(null, SiteMap.CurrentNode.Title));
                bctFilAriane.Breadcrumbs = breadcrumbs;
                bctFilAriane.DataBind();
            }
        }

        private IEnumerable<Group> GetChildGroups(Guid parentId)
        {
            return SecurityManager.AllGroups
                .Where(x => x.ParentID == parentId).OrderBy(g => g.Name);
        }

        private IEnumerable<Group> GetChildGroups()
        {
            return MedianamikUser.IsSuperAdmin ?
                SecurityManager.AllGroups.Where(g => g.ID.Equals(MedianamikGroups.SuperAdmins)) :
                MedianamikUser.Groups.GetChildGroups(1).OrderBy(g => g.Name);
        }
    }
}